class: center, middle, inverse, title-slide .title[ # ECD liveTFL ] .subtitle[ ## Experience and feedback on an application based on the teal framework ] .author[ ### Kaiping Yang, Jie Liu, Carrie Shi ] .author[ ### Cheng Zhang, Yuhang Liu, Shuang Gao, Yusi Liu ] .institute[ ### BeiGene ] --- <!-- xaringan:::inf_mr() --> <!-- https://www.garrickadenbuie.com/ --> ## Agenda .left-column[ - **Introduction** - **ECD LiveTFL** - **Advantages** - **Usage process** - **Flow chart** - **Data Process** - **Configuration Files** - **TFL Platform** - **Experience** - **Feedback** - **Summary** ] .right-column[ <center><img src="files/logo.png" /></center> ] --- ## Introduction **ECD LiveTFL** is a web app developed based on the R teal framework (interactive Exploratory Data Analysis with Shiny Web-Applications), which can provide real-time and interactive clinical trial data analysis results (TFL) display to support data-driven decision making. ### teal framework The teal framework is a tool for building TFL interactive analysis web applications, which includes the following components: - **teal**: A Exploratory Web Apps package for Analyzing Clinical Trials Data - **teal.data**: A package for defining data models and loading data sources - **teal.transform**: Functions for extracting and merging data - **teal.code**: A class for storing and executing code - **teal.widgets**: A package for creating shiny widgets - **teal.logger**: A package for setting up logging - **teal.reporter**: A tool for generating reports - **teal.modules.general**: A package for adding general modules to teal applications - **teal.modules.clinical**: A package for adding standard clinical output modules to teal applications --- ## ECD LiveTFL .panelset[ .panel[.panel-name[Introduction] .left-column[ <center><img src="files/logo.png" /></center> ] .right-column[ ![](files/introduction.jpg) ] ] .panel[.panel-name[Data Process] <center><img src="files/data_process1.jpg" height="350px" /></center> ] .panel[.panel-name[TFL Platform] <center><img src="files/t_dm.jpg" height="350px" /></center> ] ] --- ## Advantages Compared to **traditional TFL**, **ECD LiveTFL** has the following advantages: - **Centralization**: All data and code are stored on the server side, no need to install or update software locally - **Real-time**: All outputs are generated based on the latest EDC data, no need to wait or refresh - **Interactivity**: Users can adjust the output results dynamically by selecting different parameters through the UI, such as study, phase, snapshot date, group, filter, etc. - **Exploratory**: Users can view the distribution of each variable through the variable browser, view different levels of statistical results through tables, listings, figures, and combine and download selected outputs through the report previewer - **Possibility**: Users can customize the output content and format through the configuration file database and permission management system, increasing flexibility and quality control --- ## Usage process ECD LiveTFL consists of three parts: data processing, configuration files and TFL platform. - **Data Process**: Users first select different clinical trial study, phase and snapshot date through the data processing app to generate ADAM data for subsequent TFL analysis. - **Configuration Files**: Data preprocessing and subsequent TFL platforms were dynamically updated through the configuration files of different studies. - **TFL Platform**: Using the TFL platform app to read the processed data from the previous app to perform TFL interactive analysis. --- ### Flow chart .panelset[ .panel[.panel-name[Overview] ![flowchart](files/flowchart1.jpg) ] .panel[.panel-name[Data Flow] ![flowchart](files/flowchart2.jpg) ] .panel[.panel-name[Trigger] ![flowchart](files/flowchart3.jpg) ] ] --- ### Data Process .panelset[ .panel[.panel-name[Choose Study] <center><img src="files/data_process1.jpg" height="350px" /></center> ] .panel[.panel-name[Data Processing] <center><img src="files/data_process2.jpg" height="350px" /></center> ] .panel[.panel-name[Ready to TFL] <center><img src="files/data_process3.jpg" height="350px" /></center> ] ] --- ### Configuration Files .panelset[ .panel[.panel-name[table preprocessing] <center><img src="files/config_table.jpg" height="100%" /></center> ] .panel[.panel-name[listing preprocessing] <center><img src="files/config_listing.jpg" height="100%" /></center> ] .panel[.panel-name[module parameter] <center><img src="files/config_module.jpg" height="350px" /></center> ] ] --- ### Configuration Files #### Update TFL layout dynamically .panelset[ .panel[.panel-name[Choose All Phase] .pull-left[ <center><img src="files/app_select_layout1.jpg" height="100%" /></center> ] .pull-right[ <center><img src="files/app_layout1.jpg" height="100%" /></center> ] ] .panel[.panel-name[Choose Phase 1] .pull-left[ <center><img src="files/app_select_layout2.jpg" height="100%" /></center> ] .pull-right[ <center><img src="files/app_layout2.jpg" height="100%" /></center> ] ] ] --- ### TFL Platform The TFL Platform app has 8 tabs, which are: - **Introduction**: Introduction of Study information - **Tables**: Displays summary tables, allowing you to select different table types and parameters, as well as filter by grouping variables and filtering conditions - **Figures**: Displays dynamic graphs, allowing you to select different graph types and parameters, as well as filter by grouping variables and filtering conditions - **Listings**: Displays data listings, allowing you to select different listing types and parameters, as well as sort and filter by sorting variables and filtering conditions - **Data Tables**: Displays tables of all source data (ADaM) in the current session, allowing you to view the structure and content of each table - **Variable Browser**: Displays the distribution of each variable, allowing you to select different variable types and statistical methods, as well as whether to stratify by grouping variables - **User Manual**: User Manual of ECD liveTFL - **Report previewer**: Displays the report preview interface, allowing you to combine and select outputs from the previous tabs and download them in PDF or PPT format --- #### Tables .panelset[ .panel[.panel-name[dm table] <center><img src="files/t_dm.jpg" height="500px" /></center> ] .panel[.panel-name[aesum table] <center><img src="files/t_aesum.jpg" height="500px" /></center> ] .panel[.panel-name[aept table] <center><img src="files/t_aept.jpg" height="500px" /></center> ] .panel[.panel-name[aesocpt table] <center><img src="files/t_aesocpt.jpg" height="500px" /></center> ] ] --- #### Figures .panelset[ .panel[.panel-name[swimlane figure] <center><img src="files/f_swimlane.jpg" height="90%" /></center> ] ] --- #### Listings .panelset[ .panel[.panel-name[disposition listing] <center><img src="files/l_ds.jpg" height="90%" /></center> ] ] --- #### Download .panelset[ .panel[.panel-name[Download Table] <center><img src="files/download_table.jpg" height="100%" /></center> ] .panel[.panel-name[html format] <center><img src="files/download_table_html.jpg" height="100%" /></center> ] .panel[.panel-name[docx format] <center><img src="files/download_table_docx.jpg" height="100%" /></center> ] ] --- #### Download .panelset[ .panel[.panel-name[Download Listing] <center><img src="files/download_listing.jpg" height="100%" /></center> ] .panel[.panel-name[html format] <center><img src="files/download_listing_html.jpg" height="500px" /></center> ] .panel[.panel-name[docx format] <center><img src="files/download_listing_docx.jpg" height="100%" /></center> ] ] --- #### User manual .panelset[ .panel[.panel-name[User manual] <center><img src="files/user_manual1.jpg" height="100%" /></center> ] ] --- ## Experience The teal framework passes in data before starting a session. This creates difficulties when we want to start different data after the session using user information. .panelset[ .panel[.panel-name[R Code] ```r app <- init( data = teal_data( dataset("iris", iris), dataset("mtcars", mtcars) ), modules = example_module(label = "example teal module"), title = "App title", header = tags$h1("Sample App"), footer = tags$p("Copyright 2017 - 2023") ) shinyApp(app$ui, app$server) ``` ] .panel[.panel-name[App] <center><img src="files/teal_example.png" height="350px" /></center> ] ] --- ## Experience Fortunately, we can use the renderUI function to render the teal framework to uiOutput, so that the shiny app nested the teal app to start the session and load the data. However, the nested teal app cannot adapt to the screen size, and the default height is 400px. .panelset[ .panel[.panel-name[R Code] ```r ui <- fluidPage( uiOutput("tfl", style = "height: 100%; width: 100%;") ) server <- function(input, output, session) { user_name <- session$user %>% str_replace_all("\\.","_") %>% tolower() observeEvent(shinybrowser::get_height(),{ output$tfl <- renderUI({ source("teal_config.R", local = TRUE) shinyApp(ui = app$ui, server = app$server) }) }) } shinyApp(ui, server) ``` ] .panel[.panel-name[App] <center><img src="files/app_400px.jpg" height="300px" /></center> ] ] --- ## Experience Fortunately, we can make nested teal apps adaptive to screen size through the **shinybrowser** package. .panelset[ .panel[.panel-name[R Code] ```r ui <- fluidPage( shinybrowser::detect(), uiOutput("tfl", style = "height: 100%; width: 100%;") ) server <- function(input, output, session) { user_name <- session$user %>% str_replace_all("\\.","_") %>% tolower() observeEvent(shinybrowser::get_height(),{ output$tfl <- renderUI({ source("teal_config.R", local = TRUE) shinyApp(ui = app$ui, server = app$server, options =list(height = paste0(shinybrowser::get_height(),"px"), width = "100%")) }) }) } shinyApp(ui, server) ``` ] .panel[.panel-name[App] <center><img src="files/t_dm.jpg" height="500px" /></center> ] ] --- ## Experience Another problem with nested teal apps is that DT packages may not render the table correctly. .panelset[ .panel[.panel-name[R Code] ```r ui <- fluidPage( uiOutput("tfl") ) server <- function(input, output, session) { output$tfl <- renderUI({ ui <- fluidPage( DT::dataTableOutput("table") ) server <- function(input, output, session) { output$table <- DT::renderDataTable({ DT::datatable(iris) }) } shinyApp(ui, server, options = list(height = "800px", width = "100%")) }) } shinyApp(ui, server) ``` ] .panel[.panel-name[App] <center><img src="files/app_DT.jpg" height="350px" /></center> ] ] --- ## Experience One solution is to use the parameter **server = FALSE** to make the DT render the table on the front end. .panelset[ .panel[.panel-name[R Code] ```r ui <- fluidPage( uiOutput("tfl") ) server <- function(input, output, session) { output$tfl <- renderUI({ ui <- fluidPage( DT::dataTableOutput("table") ) server <- function(input, output, session) { output$table <- DT::renderDataTable({ DT::datatable(iris) }, server = FALSE) } shinyApp(ui, server, options = list(height = "800px", width = "100%")) }) } shinyApp(ui, server) ``` ] .panel[.panel-name[App] <center><img src="files/app_DT2.jpg" height="350px" /></center> ] ] --- ## Experience An html file in the absolute path can be loaded in a shiny app using **addResourcePath()**. Using **renderUI()** to render html files prevents loaded html scripts from interacting with the css style of the shiny app. .panelset[ .panel[.panel-name[R Code] ```r ui <- fluidPage( uiOutput("user_manual") ) server <- function(input, output, session) { addResourcePath("files", "/teal/files") output$user_manual <- renderUI({ tags$iframe(style="height:800px; width:100%; scrolling=yes; border: none;", src="files/user_manual.html") }) } shinyApp(ui, server) ``` ] .panel[.panel-name[App] <center><img src="files/user_manual2.jpg" height="300px" /></center> ] ] --- ## Feedback The future development direction of ECD LiveTFL is to further optimize user experience and meet user needs through user satisfaction and suggestions. ### tern package - Give users more space to customize statistical functions and results. For example: - Provide freedom to modify quantiles label format - Provide freedom to modify statistical result format, such as not showing percentage sign - Provide freedom to modify quantiles label format - Provide freedom to modify statistical result format, such as not showing percentage sign --- ## Feedback ### teal package - Page layout improvement: - Add more layout frameworks, such as shinydashboard. - Add drop-down tab function. When the analysis display of table listing figure is too much, the drop-down function of the page tab will make the page more concise and easy to use. The current page tab can only use nesting function, which can not fully meet the needs of users. - Add more layout frameworks, such as shinydashboard. - Add drop-down tab function. When the analysis display of table listing figure is too much, the drop-down function of the page tab will make the page more concise and easy to use. The current page tab can only use nesting function, which can not fully meet the needs of users. --- ## Feedback ### teal.reporter package - Enhance download function: - Enhance PDF and PPT rendering effects. Solve the problems of data truncation, poor layout, etc. - Enhance developer's ability to customize report file style. - The reporter preview interface currently provided requires adding an add card button to each report ui in the previous tab page to achieve the function of integrating and downloading all outputs. Consider adding a default function to download all TFL content from the previous tab pages in the reporter preview interface. --- ## Summary ECD LiveTFL expands on the functionality of the teal framework in the following ways: -- 1. By **connecting two apps**, it expands the functionality of the teal framework, allowing it to produce different ADAM data for displaying TFL after data preprocessing based on simple UI operations by users, enhancing the interactivity of data preprocessing. It delivers data specific to each user through permission management. -- 2. By building a **configuration file** database for different studies and combining it with UI, it allows users to dynamically modify configuration files in real time and feedback to the server side to produce interactive TFLs, further enhancing the interactivity of TFLs in more detail. By using leader programmer for unified permission management, it ensures the quality of TFL while maintaining its flexibility. -- 3. **Enhanced** listing display, filtering, searching, downloading and other functions. And by using related tables to achieve unified filtering of all listings. -- --- class: center, middle # Thanks! ### ECD liveTFL Team